import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_dva_hooks/flutter_dva_hooks.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:todo_app/components/TextExt.dart';
import 'package:todo_app/controllers/GroupController.dart';
import 'package:todo_app/controllers/MessageController.dart';
import 'package:todo_app/controllers/UserController.dart';
import 'package:todo_app/controllers/definitions/HistoryMessageParams.dart';
import 'package:todo_app/controllers/definitions/UserModel.dart';
import 'package:todo_app/hooks/EasyRefreshController.dart';
import 'package:todo_app/layout/Gaps.dart';
import 'package:todo_app/models/getters.dart';
import 'package:todo_app/pages/message/components/MessageBubble.dart';
import 'package:todo_app/pages/message/definitions/WrapMessage.dart';
import 'package:todo_app/pages/person/component/UserCard.dart';
import 'package:todo_app/utils/mqtt/MessageDBUtils.dart';
import 'package:todo_app/utils/mqtt/MessageEventBus.dart';
import 'package:todo_app/utils/mqtt/UserDBUtils.dart';

extension LocalMessageList on List<LocalMessage> {
  List<LocalMessage> get list {
    var messageList = <LocalMessage>[];
    var listIterable = where((element) => [ViewMessageType.message].contains(element.viewType));
    if(listIterable.isEmpty) return [];
    messageList.add(listIterable.first);
    listIterable.reduce((prev, element) {
      bool section = MessageModelExt.isSameSection(prev, element);
      messageList.add(element);
      if(section == false) {
        var json = element.toJson();
        json['section'] = true;
        var sectionMsg = LocalMessage()..fromJson(json);
        sectionMsg.viewType = ViewMessageType.section;
        messageList.add(sectionMsg);
      }
      return element;
    });
    return messageList;
  }

  insertLocalMessage(LocalMessage msg, {
    required ValueChanged<LocalMessage> onFilter
  }) {
    var localMsgList = where((element) => element.viewType == ViewMessageType.message);
    var ids = localMsgList.map<String?>((e) => e.mid );
    if(ids.contains(msg.mid)) {
      var oldMsg = localMsgList.firstWhere((element) => element.mid == msg.mid);
      // 对老数据进行过滤操作
      onFilter(oldMsg);
    } else {
      // 添加本地消息
      add(msg);
      // 存储在本地
      MessageDBUtils.saveMessage(msg);
    }
    // 重新排序
    sort((a, b) {
      if(a.sendDt == null && b.sendDt == null) return 0; 
      return b.sendDt!.millisecondsSinceEpoch - a.sendDt!.millisecondsSinceEpoch;
    });
  }
}

typedef QueryUserByID = UserModel Function(num? id);

class MessageList extends HookWidget {
  final MessageCategory category;
  final int rid;

  const MessageList({super.key, required this.rid, required this.category });

  @override
  Widget build(BuildContext context) {
    var store = useDvaStore();
    var me = store.rootState.system?.user;
    var meUid = store.rootState.system?.user?.id;
    var users = useState<List<UserModel>>([]);
    var messages = useState<List<LocalMessage>>([]);
    var queryUserById = useCallback<QueryUserByID>((num? id) {
        return users.value.firstWhere((element) => element.id == id, orElse: ()=> UserModel());
    }, [users.value]);
    var refreshKey = useState(0);
    var currentMessage = useState(LocalMessage());
    var controller = useEasyRefreshController();

    useEffect(() {
      

      if(category == MessageCategory.group) {
        GroupController.usersUsingGet(rid.toString()).then((res) {
          if(res.status == "success") {
            users.value = res.data ?? [];
            for (var element in users.value) {
              UserDBUtils.saveUser(element);
            }
          }
        });
      } else {
        UserDBUtils.queryUserById(rid).then((value) {
          if(value != null) users.value = [me!, value];
        });
        UserController.userInfoUsingGet(rid.toString()).then((res) {
          if(res.status == "success" && res.data != null) {
            users.value =  [me!, res.data!];
            UserDBUtils.saveUser(res.data!);
          }
        });
      }
      var sub = MessageEventBus.eventBus.on<MessageResponse>().asBroadcastStream().listen((res) {
        messages.value.insertLocalMessage(res.payload, onFilter: (msg) {
          if(res.type == MessageResponseType.sendMsg) {
            msg.sending = true;
            msg.sendError = false;
          }
          if(res.type == MessageResponseType.publishedMsg) {
            msg.sending = false;
            msg.sendError = false;
          }
          if(res.type == MessageResponseType.sendMsgError) {
            msg.sending = false;
            msg.sendError = true;
          }
          if(res.type == MessageResponseType.receivedMsg) {
            msg.sending = false;
            msg.sendError = false;
          }
        });
        currentMessage.value = res.payload;
      });
      return () {
        sub.cancel();
      };
    }, []);

    useEffect(() {
      MessageDBUtils.queryHistoryMsgList(meUid!, category, rid).then((list) {
        messages.value = list;
      }).whenComplete(() {
        MessageController.historyUsingPost(HistoryMessageParams()
          ..category = category.name
          ..rid = rid
        ).then((res) {
          if(res.status == 'success') {
            res.data?.forEach((element) {
              var message = LocalMessage()..fromJson(element.toJson());
              message.viewType = ViewMessageType.message;
              message.userId = meUid;
              messages.value.insertLocalMessage(message, onFilter: (msg)=> {});
            });
            currentMessage.value = LocalMessage();
          }
        });
      });
      return () {};
    }, [refreshKey.value]);

    return EasyRefresh(
      controller: controller,
      onRefresh: () {
        refreshKey.value += 1;
      },
      onLoad: () {
        var lastMsg = messages.value.list.lastOrNull;
        MessageDBUtils.queryHistoryMsgList(meUid!, category, rid, before: lastMsg?.sendDt).then((list) {
          messages.value.addAll(list);
        });
      },
      child: CustomScrollView(
        reverse: true,
        slivers: [
          SliverList.list(
            children: messages.value.list.map<Widget>((e) {
              if(e.viewType == ViewMessageType.section) {
                return MessageSection(dateTime: e.sendDt!);
              }
              else if(e.viewType == ViewMessageType.tips) {
                return MessageTips(tips: e.content ?? "");
              }
              else if(e.viewType == ViewMessageType.system) {
                return MessageTips(tips: e.content ?? "");
              }
              if(e.type == MessageType.text.name) {
                return MessageBubble(
                  content: TextExt.title(e.content!),
                  isMe: e.checkIsMe(meUid),
                  icon: UserAvatar(size: 32.dp, url: e.checkIsMe(meUid) ? me?.avatar : queryUserById(e.suid).avatar,)
                );
              }
              return const SizedBox();
            }).toList()
          )
        ],
      ),
    );
  }
}